#!/usr/bin/env python

from pyxmpp.all import JID,Iq,Presence,Message,StreamError
from pyxmpp.jabber.client import JabberClient
from pyxmpp.interface import implements
from pyxmpp.interfaces import *
from pyxmpp.streamtls import TLSSettings
import gootalk
import userman
import logging
import chardet

clientInstance = None

class VersionHandler(object):
    
    implements(IIqHandlersProvider, IFeaturesProvider)

    def __init__(self, client):
        self.client = client

    def get_features(self):
        return ["jabber:iq:version"]

    def get_iq_get_handlers(self):
        return [("query", "jabber:iq:version", self.get_version),]

    def get_iq_set_handlers(self):
        return []

    def get_version(self,iq):
        iq=iq.make_result_response()
        q=iq.new_query("jabber:iq:version")
        q.newTextChild(q.ns(),"name","GooTalk PyXMPP")
        q.newTextChild(q.ns(),"version","1.0")
        return iq

class GooTalkHandler(object):

    implements(IMessageHandlersProvider, IPresenceHandlersProvider)
    
    def __init__(self, client):
        self.client = client
    
    def get_message_handlers(self):
        return [("normal", self.message),]

    def get_presence_handlers(self):
        return [
            (None, self.presence),
            ("unavailable", self.presence),
            ("subscribe", self.presence_control),
            ("subscribed", self.presence_control),
            ("unsubscribe", self.presence_control),
            ("unsubscribed", self.presence_control),
            ]

    def message(self,stanza):
        body=stanza.get_body()
        if(body == None):
            return
        logging.info(body)
        body_encoding = chardet.detect(body)
        logging.info(u'message encoding %s'% (body_encoding))
        logging.info(u'message %s %s' % (stanza.get_from().as_string(), body))
        if stanza.get_type()=="headline":
            logging.info(u'messaged headline')
            return True
        logging.info(u'message deal body')
        logging.info(u'message gootalk.onMessage ')
        gootalk.onMessage(stanza.get_from().as_string(), body)
        logging.info(u'message %s %s' % (stanza.get_from().as_string(), body))

    def presence(self,stanza):
        t=stanza.get_type()
        available = True
        if t=="unavailable":
            available = False
        userman.setAvailable(stanza.get_from().as_string(), available)

    def presence_control(self,stanza):
        msg=unicode(stanza.get_from())
        t=stanza.get_type()
        if t=="subscribe":
            msg+=u" has requested presence subscription."
        elif t=="subscribed":
            userman.addUser(stanza.get_from().as_string()) 
        elif t=="unsubscribe":
            msg+=u" has canceled his subscription of our."
        elif t=="unsubscribed":
            msg+=u" has canceled our subscription of his presence."

        return stanza.make_accept_response()

class PyJabberClient(JabberClient):
    
    def __init__(self, node, domain, resource, password):
        jid = JID(node, domain, resource)
        JabberClient.__init__(self, jid, password,
                    tls_settings = TLSSettings(require = True, verify_peer = False), 
                    auth_methods=['sasl:PLAIN'], keepalive = 1
                )
        self.interface_providers = [
                VersionHandler(self),
                GooTalkHandler(self),
            ]

    def stream_closed(self, stream):
       	logging.info('Stream Closed!')

    def stream_error(self, err):
        logging.error(err.get_message())
